<?php
 /**     
  *
  * Copyright (c) 2009, Persistent Systems Limited
  *
  * Redistribution and use, with or without modification, are permitted 
  *  provided that the following  conditions are met:
  *   - Redistributions of source code must retain the above copyright notice, 
  *     this list of conditions and the following disclaimer.
  *   - Neither the name of Persistent Systems Limited nor the names of its contributors 
  *     may be used to endorse or promote products derived from this software 
  *     without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
/** 
 * File path for constants.inc
 */
require_once 'ServiceBus/constants.inc';
/** 
 * File path for DotNetServicesEnvironment.php
 */
require_once 'DotNetServicesEnvironment.php';
/** 
 * File path for /MessageBufferPolicy.php
 */
require_once 'ServiceBus/MessageBufferPolicy.php';
/** 
 * File path for Scope.php
 */
require_once 'ACS/Scope.php';
/** 
 * File path for MessageBufferClient.php
 */
require_once 'ServiceBus/MessageBufferClient.php';
/** 
 * File path for HttpWebProxy.php
 */
require_once 'util/HttpWebProxy.php';

/**
 * PollingService class for polling request from client to service bus
 * @access public
 */
class PollingService
{
	
	/**
	 * Class constructor
	  * @access public
 	 */
	function __construct()
	{
		//set max execution time to 180 sec
		set_time_limit (0); 
	}
	
	/**
     * Starts polling service.Keeps listing to "service message buffer".On receving message 
     * preapares a curl request by decodig the xml message , sends the response recieved to 
	 * the message buffer specified in incomming message from the service bus
     * @param object $scope  object of scope class
	 * @param object $policy  object of policy class
	 * @param String $messageBufferName  Name of message buffer to listen to
	 * @param object $httpWebProxy  object of httpWebProxy class
     * 
     * @access public
     */
	public function startPolling($scope,$policy,$messageBufferName,$httpWebProxy)
	{ 
		$messageBufferUri = DotNetServicesEnvironment::getMessageBufferUri("http" ,$scope->getServiceNamespaceDomain(),$messageBufferName) ;
		$client = new MessageBufferClient($messageBufferUri,$scope,$policy,$httpWebProxy);
		$client->createMessageBuffer($policy);

		$shutDown = false; 
	
		while(!$shutDown)
		{
			$requestInfoXML = $client->getMessage();
			
			preg_match('/<request(.*)?>(.*)?<\/request>/', html_entity_decode($requestInfoXML), $match);
			if(isset($match[0])){
				$requestInfoXML = $match[0];
			}
			 
			if($requestInfoXML=='<request>Stop Polling Service</request>')
			{
				$shutDown = true;
				$client->DeleteMessageBuffer($policy);
				exit;	
			}

			$request = $this->_parseMessage($requestInfoXML);
			


			if(is_array($request))
			{
				$atomResponse = $this->_getRequest($request);
				$this->_sendRequest($atomResponse,$scope,
								$policy,$request['MessageBufferName'],$httpWebProxy);
			}
		}
	}	

	/**
     * Stop polling service.
     * @param object $scope  object of scope class
	 * @param object $policy  object of policy class
	 * @param String $messageBufferName  Name of message buffer to listen to
	 * @param object $httpWebProxy  object of httpWebProxy class
     * 
     * @access public
     */
	function stopPolling($scope,$policy,$messageBufferName,$httpWebProxy)
	{
		$messageBufferUri = DotNetServicesEnvironment::getMessageBufferUri("http" ,$scope->getServiceNamespaceDomain(),$messageBufferName) ;
		$client = new MessageBufferClient($messageBufferUri,$scope,$policy,$httpWebProxy);
		$client->sendMessage('<request>Stop Polling Service</request>');
		exit;
	}

	/**
     * parses message retrived from message buffer in XML format 
     *
     * @param string $requestInfoXML  XML message recieved from message buffer
	 * @return array $request  array of request information
     * 
     * @access private
     */
	private function _parseMessage($requestInfoXML)
	{
		
		if(strpos($requestInfoXML,'<request>')===0) // to be done 0
		{
		//parse xml to array
		$requestInfoArray =  (array)simplexml_load_string($requestInfoXML);
		}
		else
		{
			return false;
		}

	

		//url 
		$request['Url'] = urldecode($requestInfoArray['url']);
		$request['Verb'] = urldecode($requestInfoArray['verb']);
		$request['MessageBufferName'] = urldecode($requestInfoArray['messageBufferName']);
		$request['Body'] = urldecode($requestInfoArray['body']);
		foreach( $requestInfoArray['headers']->children() as $headers)
		{
				
			$headers =  (array)$headers;
			$request['Headers'][$headers['name']] = urldecode($headers['value']);
		}
	
		return $request;
	}

	/**
     * fires a cURL request to REST webservice and returns response  
     *
     * @param array $request  array of request information 
	 * @return string $atomResponse  atom response from webservice
     * 
     * @access private
     */
	private function _getRequest($request)
	{
		//create object of CurlRequest class  
		$curlRequest = new CurlRequest($request['Url']);
		
		//set the messsage buffer policy
		$curlRequest->httpVerb= $request['Verb'];

		if(strtolower($request['Verb'])=='post')
		{
			//set the messsage buffer policy
			$curlRequest->postFields= $request['Body'];
		}

		if(strtolower($request['Verb'])=='put')
		{
			//set the messsage buffer policy
			$curlRequest->putFields= $request['Body'];
		}
		
	    //set the auth headers to curl transfer 
		$curlRequest->httpHeaders = $request['Headers'];

		//process the curl transfer
		$atomResponse = $curlRequest->process();	
	
		$response['requestInfo']  = $curlRequest->getInfo();
		$response['response'] = $atomResponse;	
		$response['http_code'] = $response['requestInfo']['http_code'];
		$response['curl_errors']  = $curlRequest->getErrorNo();
		return $response;
	}

	/**
     * fires a cURL request to REST webservice and returns response  
     *
	 * @param string $atomResponse  atom response string recieved from webservice
	 * @param object $scope  object of Scope class
	 * @param object $policy  object of policy class
	 * @param String $messageBufferName  Name of message buffer to listen to
	 * @param object $httpWebProxy  object of httpWebProxy class
     * 
     * @access private
     */
	private function _sendRequest($response,$scope,$policy,$messageBufferName,$httpWebProxy)
	{
		$messageBufferUri = DotNetServicesEnvironment::getMessageBufferUri("http" ,
														$scope->getServiceNamespaceDomain(),$messageBufferName) ;
		$resopnseClient = new MessageBufferClient($messageBufferUri,$scope,
														$policy,$httpWebProxy); 
		$atomResponse = '<data><responseBody>'.$response['response'].'</responseBody><responseCode>'.$response['http_code'].'</responseCode></data>';	
		$resopnseClient->sendMessage($atomResponse);
		 
	}
}

?>